﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.JointJog.CApKinJointJogApp
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using EngineeringInternalExtension;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Windows.Forms;
using Tecnomatix.Engineering;
using Tecnomatix.Engineering.Ui;


namespace DnProcessSimulateCommands.JointJog;

public class CApKinJointJogApp
{
  public const double KIN_JOINT_NO_LIMIT_VALUE = 999999.0;
  public const double KIN_REVOLUTE_JOINT_NO_LIMIT_VALUE = 17453.27507;
  private const double KIN_TRUNCATED_REVOLUTE_JOINT_NO_LIMIT_VALUE = 17453.0;
  private const double EPSILON_PERCENTAGE = 0.01;
  private const double JOINT_SPECIFIC_EPSILON = 1E-06;
  private Dictionary<CApKinJointJogApp.KeyPair, CUiKinJointJogNodeData> m_objectToNodeDataMap = new Dictionary<CApKinJointJogApp.KeyPair, CUiKinJointJogNodeData>();
  private List<TxJoint> m_externalAxesToRemove = new List<TxJoint>();
  private const int DEFAULT_MAX_DIGITS_AFTER_DECIMAL_POINT = 9;
  private const int DEGREES_MAX_DIGITS_AFTER_DECIMAL_POINT = 9;

  public event CApKinJointJogApp.CApKinJointJogOptionsChangeHandler OptionsChange;

  public event CApKinJointJogApp.CUiKinJointJogJointLimitsControlsEnteredHandler LimitsControlsEntered;

  public event CApKinJointJogApp.CUiKinJointJogJointLimitsControlsLeavedHandler LimitsControlsLeaved;

  internal IEnumerable<CUiKinJointJogNodeData> NodesDataList
  {
    get
    {
      foreach (CUiKinJointJogNodeData nodesData in this.m_objectToNodeDataMap.Values)
        yield return nodesData;
    }
  }

  private IEnumerable<CUiKinJointJogJointNodeData> JointsNodeDataList
  {
    get
    {
      foreach (CUiKinJointJogNodeData nodesData in this.NodesDataList)
      {
        if (nodesData is CUiKinJointJogJointNodeData jointsNodeData)
          yield return jointsNodeData;
      }
    }
  }

  public void ExecuteOnAllNodesData(Action<CUiKinJointJogNodeData> action)
  {
    foreach (CUiKinJointJogNodeData nodesData in this.NodesDataList)
      action(nodesData);
  }

  public void ExecuteOnJointsNodesData(Action<CUiKinJointJogJointNodeData> action)
  {
    foreach (CUiKinJointJogJointNodeData jointsNodeData in this.JointsNodeDataList)
      action(jointsNodeData);
  }

  public bool AreOutOfLimitsJoints()
  {
    bool flag = false;
    foreach (CUiKinJointJogJointNodeData jointsNodeData in this.JointsNodeDataList)
    {
      if (jointsNodeData.IsJointValueOutOfLimits())
      {
        flag = true;
        break;
      }
    }
    return flag;
  }

  public void TrimOutOfLimitsJoints()
  {
    this.ExecuteOnJointsNodesData((Action<CUiKinJointJogJointNodeData>) (nodeData => nodeData.TrimJointValueInLimits()));
  }

  public void ResetSoftLimitsToInitialValues()
  {
    this.ExecuteOnJointsNodesData((Action<CUiKinJointJogJointNodeData>) (nodeData => nodeData.ResetToInitialLimitsValues()));
  }

  public void ResetSoftLimits()
  {
    this.ExecuteOnJointsNodesData((Action<CUiKinJointJogJointNodeData>) (nodeData => nodeData.ResetToHardLimits()));
  }

  public void RefreshAllControls()
  {
    this.ExecuteOnJointsNodesData((Action<CUiKinJointJogJointNodeData>) (nodeData => nodeData.RefreshControls()));
  }

  public void DisposeNodeData()
  {
    this.ExecuteOnAllNodesData((Action<CUiKinJointJogNodeData>) (nodeData => nodeData.Dispose()));
  }

  public CUiKinJointJogDeviceNodeData GetDeviceNodeData(ITxDevice device)
  {
    if (!this.m_objectToNodeDataMap.ContainsKey(new CApKinJointJogApp.KeyPair((ITxObject) device, (ITxDevice) null)))
      this.m_objectToNodeDataMap.Add(new CApKinJointJogApp.KeyPair((ITxObject) device, (ITxDevice) null), (CUiKinJointJogNodeData) new CUiKinJointJogDeviceNodeData(this, device));
    return this.m_objectToNodeDataMap[new CApKinJointJogApp.KeyPair((ITxObject) device, (ITxDevice) null)] as CUiKinJointJogDeviceNodeData;
  }

  public CUiKinJointJogComponentNodeData GetComponentNodeData(ITxComponent component)
  {
    if (!this.m_objectToNodeDataMap.ContainsKey(new CApKinJointJogApp.KeyPair((ITxObject) component, (ITxDevice) null)))
      this.m_objectToNodeDataMap.Add(new CApKinJointJogApp.KeyPair((ITxObject) component, (ITxDevice) null), (CUiKinJointJogNodeData) new CUiKinJointJogComponentNodeData(this, component));
    return this.m_objectToNodeDataMap[new CApKinJointJogApp.KeyPair((ITxObject) component, (ITxDevice) null)] as CUiKinJointJogComponentNodeData;
  }

  public CUiKinJointJogJointNodeData GetJointNodeData(
    TxJoint joint,
    CUiKinJointJogDeviceNodeData ownerDeviceData,
    ITxDevice containerDevice,
    bool externalJoint)
  {
    if (!this.m_objectToNodeDataMap.ContainsKey(new CApKinJointJogApp.KeyPair((ITxObject) joint, containerDevice)))
      this.m_objectToNodeDataMap.Add(new CApKinJointJogApp.KeyPair((ITxObject) joint, containerDevice), (CUiKinJointJogNodeData) new CUiKinJointJogJointNodeData(this, joint, ownerDeviceData, containerDevice, externalJoint));
    return this.m_objectToNodeDataMap[new CApKinJointJogApp.KeyPair((ITxObject) joint, containerDevice)] as CUiKinJointJogJointNodeData;
  }

  public CUiKinJointJogJointNodeData GetJointNodeData(
    TxJoint joint,
    CUiKinJointJogDeviceNodeData ownerDeviceData,
    ITxDevice containerDevice)
  {
    return this.GetJointNodeData(joint, ownerDeviceData, containerDevice, false);
  }

  public void FireOptionsChanged(
    object sender,
    double prismaticStepSize,
    double revoluteStepSize,
    int customSliderSensitivity)
  {
    if (this.OptionsChange == null)
      return;
    CApKinJointJogApp.CApKinJointJogOptionsChangeEventArgs args = new CApKinJointJogApp.CApKinJointJogOptionsChangeEventArgs(prismaticStepSize, revoluteStepSize, new int?(customSliderSensitivity));
    this.OptionsChange(sender, args);
  }

  public void FireLimitsControlsEntered(object sender)
  {
    if (this.LimitsControlsEntered == null)
      return;
    this.LimitsControlsEntered(sender, new EventArgs());
  }

  public void FireLimitsControlsLeaved(object sender)
  {
    if (this.LimitsControlsLeaved == null)
      return;
    this.LimitsControlsLeaved(sender, new EventArgs());
  }

  public static int GetJointIndex(ITxDevice device, TxJoint joint)
  {
    return ((Collection<ITxObject>) device.DrivingJoints).IndexOf((ITxObject) joint);
  }

  public static Image GetObjectImage(ITxObject obj)
  {
    Image objectImage = (Image) null;
    if (obj is ITxProcessModelObject processModelObject && processModelObject.PlanningRepresentation != null)
      objectImage = processModelObject.PlanningRepresentation.PlatformServicesProvider.Icon;
    return objectImage;
  }

  public static CApKinJointJogApp.CApKinJointValueStatus GetJointStatus(TxJoint joint)
  {
    TxJointLimitStatusTypeEx jointLimitStatus = TxJointLimitUtils.GetJointLimitStatus(joint);
    bool workingLimitsCheck = TxApplication.Options.Motion.IndicateJointWorkingLimitsCheck;
    CApKinJointJogApp.CApKinJointValueStatus jointStatus;
    switch ((int) jointLimitStatus)
    {
      case 0:
        jointStatus = CApKinJointJogApp.CApKinJointValueStatus.PhysicalLimits;
        break;
      case 1:
        jointStatus = CApKinJointJogApp.CApKinJointValueStatus.PhysicalLimits;
        break;
      case 2:
        jointStatus = workingLimitsCheck ? CApKinJointJogApp.CApKinJointValueStatus.WorkingLimits : CApKinJointJogApp.CApKinJointValueStatus.None;
        break;
      case 3:
        jointStatus = workingLimitsCheck ? CApKinJointJogApp.CApKinJointValueStatus.WorkingLimits : CApKinJointJogApp.CApKinJointValueStatus.None;
        break;
      case 4:
        jointStatus = CApKinJointJogApp.CApKinJointValueStatus.None;
        break;
      default:
        jointStatus = CApKinJointJogApp.CApKinJointValueStatus.None;
        break;
    }
    return jointStatus;
  }

  public static bool IsNoLimitValue(double valueToCheck, bool isRevoluteJoint)
  {
    bool flag = false;
    double num = Math.Truncate(valueToCheck);
    if (isRevoluteJoint)
    {
      if (num == -17453.0 || num == 17453.0)
        flag = true;
    }
    else if (num == -999999.0 || num == 999999.0)
      flag = true;
    return flag;
  }

  private static double CalculateDiapazon(double? minimum, double? maximum)
  {
    return !minimum.HasValue || !maximum.HasValue ? (!minimum.HasValue || maximum.HasValue ? (minimum.HasValue || !maximum.HasValue ? double.PositiveInfinity : Math.Abs(maximum.Value)) : Math.Abs(minimum.Value)) : Math.Abs(maximum.Value - minimum.Value);
  }

  public static int CompareDoubleValues(double first, double second)
  {
    return !CApKinJointJogApp.AreEqualValues(first, second) ? (first <= second ? -1 : 1) : 0;
  }

  public static bool AreEqualValues(double val1, double val2)
  {
    double num1 = val1 - val2;
    double num2 = Math.Abs(val1) / 100.0 * 0.01;
    return Math.Abs(num1) <= num2;
  }

  public static bool JointSpecific_AreEqualValues(double val1, double val2)
  {
    return Math.Abs(val1 - val2) < 1E-06;
  }

  public static double GetRoundedJointValue(double v, bool isLinearJoint)
  {
    double num = isLinearJoint ? TxApplication.Options.Units.LinearMultiplier : TxApplication.Options.Units.AngularMultiplier;
    if (isLinearJoint || num.Equals(1.0))
    {
      int digits = Math.Min(9, CApKinJointJogApp.GetDoubleMaxSignificantDigitsAfterDecimalPoint(v));
      return Math.Round(v, digits);
    }
    double v1 = v / num;
    int digits1 = Math.Min(9, CApKinJointJogApp.GetDoubleMaxSignificantDigitsAfterDecimalPoint(v1));
    return Math.Round(v1, digits1) * num;
  }

  private static int GetDoubleMaxSignificantDigitsAfterDecimalPoint(double v)
  {
    int beforeDecimalPoint = CApKinJointJogApp.GetDigitsBeforeDecimalPoint(v);
    return beforeDecimalPoint > 15 ? 0 : 15 - beforeDecimalPoint;
  }

  private static int GetDigitsBeforeDecimalPoint(double v)
  {
    double d = Math.Abs(v);
    return d >= 10.0 ? (int) (Math.Log10(d) + 1.0) : 1;
  }

  public TxObjectList FilterRemovedAxes(ITxRobot robot)
  {
    TxObjectList externalAxes = robot.ExternalAxes;
    foreach (TxJoint txJoint in this.m_externalAxesToRemove)
      ((Collection<ITxObject>) externalAxes).Remove((ITxObject) txJoint);
    for (int index = ((Collection<ITxObject>) externalAxes).Count - 1; index >= 0; --index)
    {
      if ((((Collection<ITxObject>) externalAxes)[index] as TxJoint).Device == robot)
        ((Collection<ITxObject>) externalAxes).RemoveAt(index);
    }
    return externalAxes;
  }

  public void AddAxisToRemove(TxJoint axis) => this.m_externalAxesToRemove.Add(axis);

  public bool IsAxisToRemove(TxJoint axis) => this.m_externalAxesToRemove.Contains(axis);

  public void ResetDeviceMap() => this.m_objectToNodeDataMap.Clear();

  public delegate void CApKinJointJogOptionsChangeHandler(
    object sender,
    CApKinJointJogApp.CApKinJointJogOptionsChangeEventArgs args);

  public delegate void CUiKinJointJogJointLimitsControlsEnteredHandler(
    object sender,
    EventArgs args);

  public delegate void CUiKinJointJogJointLimitsControlsLeavedHandler(object sender, EventArgs args);

  private struct KeyPair(ITxObject obj, ITxDevice ownerDevice)
  {
    public ITxObject Object = obj;
    public ITxDevice OwnerDevice = ownerDevice;

    public override int GetHashCode()
    {
      return this.OwnerDevice != null ? this.Object.GetHashCode() ^ this.OwnerDevice.GetHashCode() : this.Object.GetHashCode();
    }

    public override bool Equals(object obj)
    {
      return obj is CApKinJointJogApp.KeyPair keyPair && this.Object == keyPair.Object && this.OwnerDevice == keyPair.OwnerDevice;
    }
  }

  public enum CApKinJointValueStatus
  {
    None,
    WorkingLimits,
    PhysicalLimits,
  }

  public class CApKinJointJogOptionsData
  {
    private Dictionary<string, int> m_columnNameToColumnIndex = new Dictionary<string, int>();
    private double m_prismaticStepSize;
    private double m_revoluteStepSize;
    private double? m_customSliderSensitivity;

    public CApKinJointJogOptionsData()
    {
      this.m_prismaticStepSize = 1.0;
      this.m_revoluteStepSize = 1.0;
      this.m_customSliderSensitivity = new double?();
    }

    public CApKinJointJogOptionsData(
      Dictionary<string, int> coll,
      double prismaticStepSize,
      double revoluteStepSize,
      double? customSliderSensitivity)
    {
      this.m_columnNameToColumnIndex = coll;
      this.m_prismaticStepSize = prismaticStepSize;
      this.m_revoluteStepSize = revoluteStepSize;
      this.m_customSliderSensitivity = customSliderSensitivity;
    }

    public Dictionary<string, int> ColumnNameToColumnIndex => this.m_columnNameToColumnIndex;

    public double PrismaticStepSize => this.m_prismaticStepSize;

    public double RevoluteStepSize => this.m_revoluteStepSize;

    public double? CustomSliderSensitivity => this.m_customSliderSensitivity;

    public static CApKinJointJogApp.CApKinJointJogOptionsData LoadOptionsData(Form form)
    {
      CApKinJointJogApp.CApKinJointJogOptionsData jointJogOptionsData = new CApKinJointJogApp.CApKinJointJogOptionsData();
      object serializedString;
      TxFormSettings.RestoreFormValue(form, "OptionsFormData", ref serializedString);
      if (serializedString != null)
        jointJogOptionsData = CApKinJointJogApp.CApKinJointJogOptionsData.DeserializeOptionsData(serializedString as string);
      return jointJogOptionsData;
    }

    public void StoreOptionsData(Form form)
    {
      string str = CApKinJointJogApp.CApKinJointJogOptionsData.SerializeOptionsData(this);
      TxFormSettings.StoreFormValue(form, "OptionsFormData", (object) str);
    }

    private static CApKinJointJogApp.CApKinJointJogOptionsData DeserializeOptionsData(
      string serializedString)
    {
      Dictionary<string, int> coll = new Dictionary<string, int>();
      string[] strArray1 = serializedString.Split('#');
      serializedString.Split(';');
      string str1 = strArray1[0];
      char[] chArray = new char[1]{ ';' };
      foreach (string str2 in str1.Split(chArray))
      {
        if (str2 != string.Empty)
        {
          string[] strArray2 = str2.Split(':');
          coll.Add(strArray2[0], Convert.ToInt32(strArray2[1]));
        }
      }
      string[] strArray3 = strArray1[1].Split(';');
      double prismaticStepSize = Convert.ToDouble(strArray3[0]);
      double revoluteStepSize = Convert.ToDouble(strArray3[1]);
      double? customSliderSensitivity = !Convert.ToBoolean(strArray3[2]) ? new double?() : new double?(Convert.ToDouble(strArray3[3]));
      return new CApKinJointJogApp.CApKinJointJogOptionsData(coll, prismaticStepSize, revoluteStepSize, customSliderSensitivity);
    }

    private static string SerializeOptionsData(
      CApKinJointJogApp.CApKinJointJogOptionsData optionsData)
    {
      string str1 = string.Empty;
      foreach (KeyValuePair<string, int> keyValuePair in optionsData.ColumnNameToColumnIndex)
        str1 = $"{str1}{keyValuePair.Key}:{keyValuePair.Value.ToString()};";
      string[] strArray = new string[6]
      {
        str1,
        "#",
        null,
        null,
        null,
        null
      };
      double num = optionsData.PrismaticStepSize;
      strArray[2] = num.ToString();
      strArray[3] = ";";
      num = optionsData.RevoluteStepSize;
      strArray[4] = num.ToString();
      strArray[5] = ";";
      string str2 = string.Concat(strArray);
      return !optionsData.CustomSliderSensitivity.HasValue ? $"{str2}{optionsData.CustomSliderSensitivity.HasValue.ToString()};3" : $"{str2}{optionsData.CustomSliderSensitivity.HasValue.ToString()};{optionsData.CustomSliderSensitivity.Value.ToString()}";
    }
  }

  public class CUiKinJointJogCheckForOutOfLimitJointsEventArgs : EventArgs
  {
    private int m_outOfLimitsJointsCount;

    public bool AreOutOfLimitJoints => this.m_outOfLimitsJointsCount > 0;

    public bool IsOutOfLimits
    {
      set
      {
        if (!value)
          return;
        ++this.m_outOfLimitsJointsCount;
      }
    }
  }

  public class CApKinJointJogOptionsChangeEventArgs : EventArgs
  {
    private double m_prismaticStepSize;
    private double m_revoluteStepSize;
    private double? m_customSliderSensitivity;

    public CApKinJointJogOptionsChangeEventArgs(
      double prismaticStepSize,
      double revoluteStepSize,
      int? customSliderSensitivity)
    {
      this.m_prismaticStepSize = prismaticStepSize;
      this.m_revoluteStepSize = revoluteStepSize;
      int? nullable = customSliderSensitivity;
      this.m_customSliderSensitivity = nullable.HasValue ? new double?((double) nullable.GetValueOrDefault()) : new double?();
    }

    public double PrismaticStepSize => this.m_prismaticStepSize;

    public double RevoluteStepSize => this.m_revoluteStepSize;

    public double? CustomSliderSensitivity => this.m_customSliderSensitivity;
  }
}
